{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9b33bc34-c874-489d-ba38-1e9ba1f1d848",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Install necessary packages\n",
    "!pip install transformers accelerate bitsandbytes pandas tqdm --quiet\n",
    "\n",
    "# Step 1: Load the model with memory-efficient settings\n",
    "from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline\n",
    "import torch\n",
    "\n",
    "model_name = \"meta-llama/Llama-3-8b-hf\"  # Hugging Face LLaMA-3-8B checkpoint\n",
    "\n",
    "# Load tokenizer\n",
    "tokenizer = AutoTokenizer.from_pretrained(model_name)\n",
    "\n",
    "# Load model with 8-bit quantization for memory efficiency\n",
    "model = AutoModelForCausalLM.from_pretrained(\n",
    "    model_name,\n",
    "    device_map=\"auto\",            # Automatically assign to GPU if available\n",
    "    torch_dtype=torch.float16,    # Use half-precision\n",
    "    load_in_8bit=True             # Enable 8-bit quantization (via bitsandbytes)\n",
    ")\n",
    "\n",
    "# Step 2: Set up generation pipeline\n",
    "generator = pipeline(\n",
    "    \"text-generation\",\n",
    "    model=model,\n",
    "    tokenizer=tokenizer,\n",
    "    max_new_tokens=100,    # Control length of output\n",
    "    do_sample=False        # Deterministic output\n",
    ")\n",
    "\n",
    "\n",
    "#Step 2. Define Korean Prompt\n",
    "def build_prompt_korean_continuous(article_text, company_name):\n",
    "    return f\"\"\"\n",
    "당신은 뉴스 기사 감성 분석가입니다. 아래 뉴스 기사가 기업 \"{company_name}\"에 대해 어떤 감정적 태도를 보이는지 분석하십시오.\n",
    "\n",
    "기사:\n",
    "\\\"{article_text.strip()}\\\"\n",
    "\n",
    "분석 항목:\n",
    "1. 감정 극성(Valence): 기사 전반에 나타난 해당 기업에 대한 평가를 0(매우 부정적)에서 1(매우 긍정적) 사이의 숫자로 정량화하십시오.\n",
    "2. 정서 강도(Arousal): 감정 표현의 강도를 0(감정이 거의 없음)에서 1(감정이 매우 강함) 사이의 숫자로 정량화하십시오.\n",
    "\n",
    "다음과 같은 형식으로 응답하십시오:\n",
    "감정 극성: [0.0 - 1.0]\n",
    "정서 강도: [0.0 - 1.0]\n",
    "\"\"\"\n",
    "\n",
    "#Step 3. Inference & Parcing Logic\n",
    "def parse_response_continuous(text):\n",
    "    valence, arousal = None, None\n",
    "    for line in text.split('\\n'):\n",
    "        if '감정 극성' in line:\n",
    "            try:\n",
    "                valence = float(line.split(\":\")[1].strip())\n",
    "            except Exception:\n",
    "                valence = None\n",
    "        elif '정서 강도' in line:\n",
    "            try:\n",
    "                arousal = float(line.split(\":\")[1].strip())\n",
    "            except Exception:\n",
    "                arousal = None\n",
    "    return valence, arousal\n",
    "\n",
    "#Step 4. Batch Processing Function\n",
    "from tqdm import tqdm\n",
    "import pandas as pd\n",
    "\n",
    "def classify_articles_continuous(df, article_col='article', company_col='company'):\n",
    "    results = []\n",
    "    for _, row in tqdm(df.iterrows(), total=len(df)):\n",
    "        article = row[article_col]\n",
    "        company = row[company_col]\n",
    "        prompt = build_prompt_korean_continuous(article, company)\n",
    "        output = generator(prompt)[0]['generated_text']\n",
    "        valence, arousal = parse_response_continuous(output)\n",
    "        \n",
    "        results.append({\n",
    "            'company': company,\n",
    "            'article': article,\n",
    "            'valence': valence,\n",
    "            'arousal': arousal\n",
    "        })\n",
    "    return pd.DataFrame(results) \n",
    "\n",
    "#Step 5. Load and Run\n",
    "df = pd.read_csv(\"full_articles.csv\")  \n",
    "results_df = classify_articles_continuous(df)\n",
    "\n",
    "# Save to disk\n",
    "results_df.to_csv(\"llama3_sentiment_results.csv\", index=False)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "64bf5778-3dbb-4cd2-abef-9bb1a228d547",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
